# -*- coding: utf-8 -*-
# created on 2016/7/15

from mathsolver.functions.base import *
from sympy import Set, S
from mathsolver.functions.mathematica.mathematicaSolve import MathematicaSolve


# 集合运算
class JiHeOperate(BaseFunction):
    @staticmethod
    def set_check(list_v, set_v, is_contain=True):
        return [num for num in list_v if set_v.contains(num) == is_contain]

    def operate(self, left_name, op, right_name):
        right = self.search(right_name) if isinstance(right_name, str) else right_name
        right_v = right.value["value"]
        right_name = right.value["name"]
        right_var = right.value["var"]
        if not left_name:
            name = "%s(%s)" % (op, right_name)
            self.label.add("补集运算")
            quanji = re.search(r"\{([A-Z])\}", op).group(1)

            if quanji != "R":
                res = self.search(quanji)
                if res:
                    if "R" in str(self.search(quanji)):
                        quanji_v = S.Reals
                    else:
                        quanji_v = res.value["value"]

                elif quanji == "":
                    quanji_v = S.Reals
            else:
                quanji_v = S.Reals

            if isinstance(quanji_v, (list, FiniteSet)) and isinstance(right_v, (list, FiniteSet)):
                v = set(quanji_v).difference(right_v)
                res = BaseInnerSet({"name": name, "var": "", "value": list(v)})
            elif isinstance(quanji_v, Set) and isinstance(right_v, Set):
                v = right_v.complement(quanji_v)
                res = BaseInnerSet({"name": name, "var": "", "value": v})
            elif isinstance(quanji_v, Set) and isinstance(right_v, list):
                res = BaseInnerSet({"name": name, "var": "", "value": self.set_check(right_v, quanji_v, False)})

        else:
            left = self.search(left_name) if isinstance(left_name, str) else left_name
            left_name = left.value["name"]
            name = "%s%s%s" % (left_name, op, right_name)
            left_v = left.value["value"]
            left_var = left.value["var"]

            if op == "∩":
                self.label.add("交集运算")
            elif op == "∪":
                self.label.add("并集运算")

            if isinstance(left_v, list):
                left_v = FiniteSet(*left_v)

            if isinstance(right_v, list):
                right_v = FiniteSet(*right_v)

            if isinstance(left_v, list) and isinstance(right_v, list):
                if op == "∩":
                    v = list(set(left_v).intersection(right_v))
                elif op == "∪":
                    v = list(set(left_v + right_v))
                res = BaseInnerSet({"name": name, "var": "", "value": v})

            elif isinstance(left_v, Set) and isinstance(right_v, Set):
                if op == "∩":
                    v = left_v.intersect(right_v)
                elif op == "∪":
                    v = left_v.union(right_v)
                res = BaseInnerSet({"name": name, "var": "", "value": v})

            elif isinstance(left_v, list) and isinstance(right_v, Set):
                if op == "∩":
                    res = BaseInnerSet({"name": name, "var": "", "value": self.set_check(left_v, right_v)})
            elif isinstance(left_v, Set) and isinstance(right_v, list):
                if op == "∩":
                    res = BaseInnerSet({"name": name, "var": "", "value": self.set_check(right_v, left_v)})
            elif len(left_var) == 2 and len(right_var) == 2:
                if isinstance(left_v, BaseEq) and isinstance(right_v, BaseEq):
                    if op == "∩":
                        stepsolver = MathematicaSolve().solver(BaseEqs([left_v.value, right_v.value]))
                        value = stepsolver.output[0].value.values()[0]
                        # stepsolver = jiefangchenzu().solver(BaseEqs([left_v.value, right_v.value]))
                        res = BaseInnerSet({"name": name, "var": "", "value": FiniteSet(*value)})

            elif (len(left_var) == 2 and len(right_var) == 1) or (len(left_var) == 1 and len(right_var) == 2):
                res = BaseInnerSet({"name": name, "var": "", "value": EmptySet})

        self.steps.append(["", res.printing()])
        return res

    def _solver(self, setop):
        if len(setop) == 2:
            op, right = setop
            if isinstance(right, list):
                right = self._solver(right)

            return self.operate("", op, right)
        elif len(setop) == 3:
            left, op, right = setop
            if isinstance(left, list):
                left = self._solver(left)

            if isinstance(right, list):
                right = self._solver(right)

            return self.operate(left, op, right)
        else:
            raise ValueError("unvalid setop")

    def solver(self, *args):
        setop = args[0].value
        res = self._solver(setop)
        self.output.append(res)
        if len(self.label.intersection(["集合的交集运算", "集合的补集运算", "集合的并集运算"])) > 1:
            self.label.add("集合综合运算")
        return self


if __name__ == '__main__':
    pass
